#include "ConcatHashTable.h"
//necessary
#include <stdlib.h>
#include "memory-tools.h"
#include "string.h"

//TODO testing
HashTable* initConcatenationHashTable(int length,AbsolutePointer hashtablePointer){
	//1: used for the size
	//length*x: used to malloc the hashtable itself
	HashTable* result=mallocMemory(1+length*sizeof(HTLocalCell),"HashTable.c:createHashTable:1");
	memset(result,0,length*sizeof(HTLocalCell));
	return result;
}

//TODO testing
void addElementInConcatenationHashTable(HashTable* ht, char* id,AbsolutePointer pointerToData,AbsolutePointer htcellpointer){

	DirectHash h=hashString(id);

	//create the new HTRemoteCell that contains the pointers to data
	if (htcellpointer==NULL){ //the new cell must be allocated manually
		htcellpointer=mallocMemory(sizeof(HTRemoteCell),"ConcatHashTable:addElementInConcatenationHashTable:1");
	}
	((HTRemoteCell*)htcellpointer)->data=pointerToData;
	((HTRemoteCell*)htcellpointer)->next=NULL;

	if ((ht->hashtable[h]).list==NULL){
		//inside the hash table there is a NULL value in the field "list":  a new list must be created
		ht->hashtable[h].list=htcellpointer;
	}else{
		//inside the has table there is non 0 value in the field "list": we tell to the tail element that it isn't the tail anymore
		((HTRemoteCell*)ht->hashtable[h].tail)->next=htcellpointer;
	}
	//we have to append the new data after the tail of the list
	ht->hashtable[h].tail=htcellpointer;
}

//TODO testing
AbsolutePointer lookElementInConcatenationHashTable(HashTable* ht,char* id){
	DirectHash h=hashString(id);
	HTRemoteCell* tmp=ht->hashtable[h].list;
	AbsolutePointer data;

	//if there isn't a list in the h-th cell, then there cannot be the data we are looking
	while(tmp!=NULL){
		data=tmp->data;
		//we know the first data of a structure is ALWAYS a char* leading to the id. We check that they are equal
		//to increase the speed of the comparison operation, we first check if the 2 very pointers are equal.
		if (((char*)data)==id){
			return data;
		}
		//if they aren't, we have to check if the 2 strings are equal
		if (strcmp((char*)data,id)==0){
			return data;
		}
		//if they are not, then we continue to the next element of the list
		tmp=tmp->next;
	}
	return NULL;
}

//TODO testing
void freeConcatenationHashTable(HashTable* ht){
	//for every HTLocalCell inside the hash table we need to free the relative list
	int localcell;
	HTRemoteCell* tmp;

	for (localcell=0;localcell<ht->size;localcell++){
		tmp=ht->hashtable[localcell].list;
		while(tmp!=NULL){
			free(tmp);
			tmp=tmp->next;
		}
	}
	//now we set to zero the entire hashtable structure: in this way the developer can't write on unallocated
	//memory anymore
	memset(ht->hashtable,0,ht->size);
	ht->size=0;
}


